package com.syni.mdd.yhd.common.all.service;

import com.syni.mdd.sjb.common.component.utils.common.utils.ArithUtil;
import com.syni.mdd.sjb.common.component.utils.common.utils.ResultMapHelper;
import com.syni.mdd.yhd.common.all.constants.Constants;
import com.syni.mdd.yhd.common.all.constants.ResultCode;
import com.syni.mdd.yhd.common.all.constants.ResultMsg;
import com.syni.mdd.yhd.common.all.dao.jpa.BmsUserVideoDkDao;
import com.syni.mdd.yhd.common.all.dto.reponseDto.dk.BusinessDkDataRpDto;
import com.syni.mdd.yhd.common.all.entity.*;
import com.syni.mdd.yhd.common.all.entity.user.BmsUser;
import com.syni.mdd.yhd.common.all.service.impl.BaseService;
import com.syni.mdd.yhd.common.all.utils.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.servlet.http.HttpServletResponse;
import java.util.*;
import java.util.stream.Collectors;

/**
 * @className BmsUserVideoLikeService
 * @description 用户与商家点赞
 * Author cfx
 * @DATE 2019/4/8 9:42
 * @VERSION 1.0
 **/

@Service
public class BmsUserVideoDkService extends BaseService<BmsUserVideoDk,Integer> {

    public final static Integer add = 1;

    public final static Integer subduction = -1;

    @Autowired
    BmsVideoService bmsVideoService;

    @Autowired
    BmsUserVideoDkDao bmsUserVideoDkDao;

    @Autowired
    BmsBusinessService bmsBusinessService;

    @Autowired
    BmsUserService bmsUserService;

    @Autowired
    BmsBusinessTypeService bmsBusinessTypeService;

    @Autowired
    BmsUserVideoService bmsUserVideoService;

    @Autowired
    BmsDxOrderService bmsDxOrderService;

    @Autowired
    BmsDxGroupBuyUseService bmsDxGroupBuyUseService;

    @Autowired
    BmsDxGroupBuyService bmsDxGroupBuyService;

    @Autowired
    BmsDxClientRoleService bmsDxClientRoleService;

    @Autowired
    RedisTemplate redisTemplate;

    @Override
    public BmsUserVideoDkDao getBaseDao() {
        return bmsUserVideoDkDao;
    }

    @Transactional
    public Map<String,Object> operationDk(Integer userId, Integer videoId) {
        Optional<BmsVideo> bmsVideoOptional = bmsVideoService.getBaseDao().findById(videoId);
        if(!bmsVideoOptional.isPresent()){
            return ResultMapHelper.failure("该视频不存在！");
        }
        BmsVideo bmsVideo = bmsVideoOptional.get();
        Optional<BmsBusiness> bmsBusinessOptional = bmsBusinessService.getBaseDao().findById(bmsVideo.getBmsId());
        if(!bmsBusinessOptional.isPresent()){
            return ResultMapHelper.failure("该店铺不存在！");
        }
        BmsBusiness business = bmsBusinessOptional.get();
        if(bmsVideo != null) {
            BmsUserVideoDk bmsUserVideoDk = bmsUserVideoDkDao.findByBmsUserIdAndBmsBusinessId(userId, business.getId());
            if (bmsUserVideoDk != null) {
                return ResultMapHelper.failure("打卡失败，重复打卡！");
            }
            bmsUserVideoDk = new BmsUserVideoDk();
            bmsUserVideoDk.setBmsUserId(userId);
            bmsUserVideoDk.setBmsBusinessId(business.getId());
            bmsUserVideoDk.setDkTime(new Date());
            bmsUserVideoDkDao.save(bmsUserVideoDk);
            //将商家打卡数+1
            //business.setDkTimes(business.getDkTimes() == null? 1 : business.getDkTimes() + 1);
            addUserDkToRedis(business.getId(),add);
            return ResultMapHelper.success(null,"打卡成功！");
        }
        return ResultMapHelper.failure("该视频不存在！");
    }

    public void addUserDkToRedis(Integer bussessId,Integer status) {
        redisTemplate.opsForZSet().incrementScore(Constants.REDIS_KEY_LIKEDK,"dk:" + bussessId,status);
    }

    /*public List<BmsUserVideoDk> getList(Integer user_id, Integer page) {
        Integer pageSize = 9;
        PageRequest pageRequest = PageRequest.of(page - 1,pageSize, Sort.Direction.DESC,"dkTime");
        List<BmsUserVideoDk> bmsUserVideoDkList = bmsUserVideoDkDao.findByBmsUserId(user_id,pageRequest);
        //getDkTime(bmsUserVideoDkList);
        return bmsUserVideoDkList;
    }*/

    public List<Map<String,Object>> getListToFront(Integer userId,String addrCity) {
        return bmsUserVideoDkDao.selfFindByBmsUserId(userId,addrCity);
    }

    public List<BmsUserVideoDk> getUserDkByUserIdAndBusinessIdIn(Integer userId,Set businessId) {
        Map<String,Object> condition = new HashMap<>();
        condition.put("bmsUserId",userId);
        condition.put("bmsBusinessId_IN",businessId);
        return bmsUserVideoDkDao.findAll(new SpecificationUtils(condition));
    }

    public List<BmsUserVideoDk> getList(Integer userId) {
        return bmsUserVideoDkDao.findByBmsUserId(userId);
    }

    /*public void getDkTime(List<BmsUserVideoDk> bmsUserVideoDkList) {
        Set<Integer> bussessIds = new HashSet<>();
        if(bmsUserVideoDkList != null & bmsUserVideoDkList.size() > 0){
            for(BmsUserVideoDk bmsUserVideoDk : bmsUserVideoDkList){
                bussessIds.add(bmsUserVideoDk.getBmsVideo().getBmsId());
            }
        }
        if(bussessIds.size() > 0) {
            Map<Integer, BmsBusiness> bmsBusinessMap = bmsBusinessService.findBusinessByIds(bussessIds);
            for (BmsUserVideoDk bmsUserVideoDk : bmsUserVideoDkList) {
                if (bmsBusinessMap.containsKey(bmsUserVideoDk.getBmsVideo().getBmsId())) {
                    bmsUserVideoDk.getBmsVideo().setLikeTimes(bmsBusinessMap.get(bmsUserVideoDk.getBmsVideo().getBmsId()).getDkTimes() == null ? 0 :
                            bmsBusinessMap.get(bmsUserVideoDk.getBmsVideo().getBmsId()).getDkTimes());
                }
            }
        }
    }*/

    public Map<String,Object> countUserStaticDk(BmsUser bmsUser, HttpServletResponse response) {
        String SHOWCOUNTCITY_ONE = "广州市";
        String SHOWCOUNTCITY_TWO = "珠海市";
        Integer defaultNum = 0;
        Map<String,Integer> eachCityDkNum = new HashMap<>();
        eachCityDkNum.put(SHOWCOUNTCITY_TWO,defaultNum);
        Map<String,Object> resultMap = new HashMap<>();
        resultMap.put("cityNum",defaultNum);
        resultMap.put("businessNum",defaultNum);
        resultMap.put("fineFoodNum",defaultNum);
        resultMap.put("eachCityDkNum",eachCityDkNum);
        //计算加入电享生活天数
        resultMap.put("passDay",calPassDay(bmsUser.getNewTime()));
        resultMap.put("customName",bmsUser.getSystemUser().getLoginName());
        resultMap.put("aliasTitle","美食爱好者");
        Set<Integer> bmsBusinessIds = new HashSet<>();

        //查询出美食分类id
        String businessTypeName = "美食";
        BmsBusinessType bmsBusinessType = bmsBusinessTypeService.findByTypeName(businessTypeName);
        List<Map<String,Object>> resultList = bmsUserVideoDkDao.findByUserId(bmsUser.getId());
        if(resultList != null && resultList.size() > 0){
            for(Map<String,Object> objectMap : resultList){
                bmsBusinessIds.add(Integer.parseInt(objectMap.get("bms_business_id").toString()));
            }
            //计算城市、商家、美食
            List<Map<String,Object>> addrCountRes = bmsBusinessService.getBaseDao().findByGroupByAddrCity(bmsBusinessIds);
            Integer businessNum = 0;
            Set<String> cityLists = new HashSet<>();
            if(addrCountRes != null && addrCountRes.size() > 0){
                for(Map<String,Object> result : addrCountRes){
                    if(result.get("addr_city") != null) {
                        Integer num = Integer.parseInt(result.get("num").toString());
                        businessNum += num;
                        cityLists.add(result.get("addr_city").toString());
                        //单独统计单个城市打卡多少
                        String city = result.get("addr_city").toString();
                        if(SHOWCOUNTCITY_ONE.equals(city) || SHOWCOUNTCITY_TWO.equals(city)) {
                            if (eachCityDkNum.containsKey(result.get("addr_city").toString())) {
                                Integer hasNum = eachCityDkNum.get(result.get("addr_city").toString());
                                eachCityDkNum.put(result.get("addr_city").toString(), hasNum + num);
                            } else {
                                eachCityDkNum.put(result.get("addr_city").toString(), num);
                            }
                        }
                    }
                }
                if(bmsBusinessType != null){
                    List<Map<String, Object>> userFineFoodNum = bmsBusinessService.getBaseDao().countUserDkInBusinessType(bmsBusinessIds,bmsBusinessType.getId());
                    if (userFineFoodNum != null & userFineFoodNum.size() > 0) {
                        Map<String, Object> resultSearch = userFineFoodNum.get(0);
                        if (resultSearch.containsKey("num")) {
                            resultMap.put("fineFoodNum", resultSearch.get("num"));
                        }
                    }
                }
                resultMap.put("cityNum",cityLists.size());
                resultMap.put("businessNum",businessNum);
                resultMap.put("eachCityDkNum",eachCityDkNum);
            }
        }
        resultMap.put("designation",toDesignation(resultMap));
        packageResultMap(resultMap);
        outImgToFront(resultMap,getResultPositionMap(),response);
        return resultMap;
    }

    public Map<String,Integer[]> getResultPositionMap() {
        Map<String,Integer[]> imageDataXyCoordinate = new HashMap<>();
        imageDataXyCoordinate.put("customName",new Integer[]{350,700});
        imageDataXyCoordinate.put("passDay",new Integer[]{500,758});
        imageDataXyCoordinate.put("passDaySecond",new Integer[]{145,815});
        imageDataXyCoordinate.put("cityNum",new Integer[]{310,815});
        imageDataXyCoordinate.put("businessNum",new Integer[]{530,815});
        imageDataXyCoordinate.put("designation",new Integer[]{200,888});
        imageDataXyCoordinate.put("aliasTitle",new Integer[]{440,953});
        imageDataXyCoordinate.put("fineFoodNum",new Integer[]{420,1020});
        imageDataXyCoordinate.put("珠海市",new Integer[]{290,630});
        imageDataXyCoordinate.put("广州市",new Integer[]{525,630});
        imageDataXyCoordinate.put("珠海广州",new Integer[]{395,630});
        return imageDataXyCoordinate;
    }

    public void packageResultMap(Map<String, Object> resultMap) {
        resultMap.put("passDaySecond",resultMap.get("passDay"));
    }

    public void outImgToFront(Map<String, Object> data,Map<String,Integer[]> positionMap,HttpServletResponse response) {
        Map<String,Integer> cityChose = (Map<String, Integer>) data.get("eachCityDkNum");
        List<String> choseKey = new ArrayList<>();
        if(cityChose.size() > 0) {
            for (Map.Entry<String, Integer> cityNode : cityChose.entrySet()) {
                choseKey.add(cityNode.getKey());
            }
        }
        String finalChoseKey = StringUtils.join(choseKey,"_");
        String imgPath = DesignationUtils.getImgPath(finalChoseKey);
        OutImageUtils.drawImg(imgPath,data,positionMap,response);
    }

    public String toDesignation(Map<String,Object> resultMap) {
        Integer businessNum = Integer.parseInt(resultMap.get("businessNum").toString());
        Integer passDay = Integer.parseInt(resultMap.get("passDay").toString());
        return DesignationUtils.getDesignation(businessNum,passDay);
    }

    private Integer calPassDay(Date newTime) {
        Date nowTime = new Date();
        long times = nowTime.getTime() - newTime.getTime();
        Integer day = (int)Math.ceil((double)times/1000/3600/24);
        return day;
    }

    public Integer findUserTotalDk(Integer userId) {
        Integer ret = 0;
        Map<String,Object> resultMap = bmsUserVideoDkDao.selfCountUserDkNum(userId);
        if(resultMap != null && resultMap.size() > 0){
            ret = Integer.parseInt(resultMap.get("num").toString());
        }
        return ret;
    }

    /**
     * @Description 查询探店图的数据
     * @Author: cfx
     * @Date: 2019/8/30
     */
    public Map<String,Object> getUserAgentShop(Integer userId) {
        //每顿下午茶25元
        final int afternoonUse = 25;
        BmsUser bmsUser = TokenManager.getUser(userId);
        if(bmsUser == null){
            return ResultMapHelper.result(ResultCode.CODE_USER_NO_EXIST,ResultMsg.CODE_USER_NO_EXIST);
        }
        final int defaultNum = Constants.COMMON_FLAG_FALSE_INT;
        BusinessDkDataRpDto businessDkDataRpDto = new BusinessDkDataRpDto();
        List<BmsDxClientRole> bmsDxClientRoles = bmsDxClientRoleService.getUserClienRole(userId,Constants.GENERAL_USER_ROLE_ID);
        if(!(bmsDxClientRoles != null && bmsDxClientRoles.size() > 0)){
            bmsDxClientRoleService.addRegisterUserRole(userId,Constants.GENERAL_USER_ROLE_ID,bmsUser.getNewTime());
        }
        BmsDxClientRole bmsDxClientRole = bmsDxClientRoles.get(0);
        businessDkDataRpDto.setPassDay(calPassDay(bmsDxClientRole.getNewTime()));
        List<Map<String,Object>> resultList = bmsUserVideoDkDao.findByUserId(userId);
        if(resultList != null && resultList.size() > 0){
            Set<Integer> bmsBusinessIds = new HashSet<>();
            for(Map<String,Object> objectMap : resultList){
                bmsBusinessIds.add(Integer.parseInt(objectMap.get("bms_business_id").toString()));
            }
            //计算城市、商家、美食
            List<Map<String,Object>> cityCount = bmsBusinessService.getBaseDao().findByGroupByAddrCity(bmsBusinessIds);
            Set<String> cityLists = new HashSet<>();
            Integer businessNum = defaultNum;
            if(cityCount != null && cityCount.size() > 0){
                for(Map<String,Object>  cityCountObj : cityCount){
                    if(cityCountObj.containsKey("addr_city") && StringUtils.checkNullAndEmpty(cityCountObj.get("addr_city"))){
                        cityLists.add(cityCountObj.get("addr_city").toString());
                    }
                    businessNum += Integer.parseInt(cityCountObj.get("num").toString());
                }
            }
            businessDkDataRpDto.setCityNum(cityLists.size());
            businessDkDataRpDto.setBusinessNum(businessNum);
        }
        businessDkDataRpDto.setDesignation(toDesignation(businessDkDataRpDto));
        //总消费
        businessDkDataRpDto.setTotalConsumption(String.valueOf((int)(Math.floor(bmsDxOrderService.countUserTotalConsum(userId)))));
        //享受过多少次团购套餐
        businessDkDataRpDto.setEnjoyGroupBuyUseNum(bmsDxGroupBuyUseService.countUserUseGroupBuyNum(userId));
        Map<String,Object> conditionMap = new HashMap<>();
        conditionMap.put("userId",userId);
        conditionMap.put("status",Constants.GROUP_ALREADY_USE);
        List<BmsDxGroupBuyUse> bmsDxGroupBuyUses = bmsDxGroupBuyUseService.getBaseDao().findAll(new SpecificationUtils(conditionMap));
        Set<Integer> groupBuyIds = bmsDxGroupBuyUses.stream().map(BmsDxGroupBuyUse::getGroupBuyId).collect(Collectors.toSet());
        Double totalSave = 0d;
        if(groupBuyIds.size() > 0){
            Map<Integer,BmsDxGroupBuy> bmsDxGroupBuyMap = bmsDxGroupBuyService.getGroupBuyById(groupBuyIds);
            for(BmsDxGroupBuyUse bmsDxGroupBuyUse : bmsDxGroupBuyUses){
                if(bmsDxGroupBuyMap.containsKey(bmsDxGroupBuyUse.getGroupBuyId())){
                    BmsDxGroupBuy bmsDxGroupBuy = bmsDxGroupBuyMap.get(bmsDxGroupBuyUse.getGroupBuyId());
                    if(bmsDxGroupBuy.getGroupValue() != null && bmsDxGroupBuy.getGroupPrice() != null) {
                        totalSave += ArithUtil.sub(bmsDxGroupBuy.getGroupValue(), bmsDxGroupBuy.getGroupPrice());
                    }
                }
            }
        }
        //System.out.println(totalSave);
        totalSave = ArithUtil.round(totalSave,2);
        businessDkDataRpDto.setSaveMoney(String.valueOf(totalSave));
        businessDkDataRpDto.setAfternoonTeaNum((int)(ArithUtil.div(totalSave,afternoonUse,0)));
        redisTemplate.opsForZSet().add(Constants.REDIS_KEY_USER_CONSUMPTION,userId,Double.parseDouble(businessDkDataRpDto.getTotalConsumption()));
        //redisTemplate.opsForZSet().
        //redisTemplate.opsForZSet().rank();
        Long size = redisTemplate.opsForZSet().size(Constants.REDIS_KEY_USER_CONSUMPTION);
        Long rankIndex = redisTemplate.opsForZSet().reverseRank(Constants.REDIS_KEY_USER_CONSUMPTION,userId);
        Integer doSize = size.intValue();
        Integer doRankIndex = rankIndex.intValue();
        Double overRate = Math.floor((doSize - doRankIndex) / (double)doSize * 100);
        Integer overRateInt = overRate.intValue();
        if(overRateInt != Constants.COMMON_FLAG_FALSE_INT){
            businessDkDataRpDto.setOverRate(String.format("%s%%",overRateInt));
        }
        return ResultMapHelper.success(businessDkDataRpDto, ResultMsg.MSG_GET_SUCCESS);
    }

    public String toDesignation(BusinessDkDataRpDto businessDkDataRpDto) {
        return DesignationUtils.getDesignation(businessDkDataRpDto.getBusinessNum(),businessDkDataRpDto.getPassDay());
    }

    public Map<String, Object> checkUserIsDk(Integer userId, Integer businessId) {
        BmsUserVideoDk bmsUserVideoDk = bmsUserVideoDkDao.findByBmsUserIdAndBmsBusinessId(userId,businessId);
        return ResultMapHelper.success(bmsUserVideoDk,ResultMsg.MSG_GET_SUCCESS);
    }
}
